home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK2.toast / Development Kits (Disc 2) / QuickDraw GX / Programming Stuff / Sample Code / Printing Samples / Applications… / Banana Jr. ƒ / printing.c < prev   
Encoding:
C/C++ Source or Header  |  1995-04-10  |  11.7 KB  |  462 lines  |  [TEXT/KAHL]

  1. /*
  2.     Printing.c
  3.     
  4.     This file contains the printing routines for "all shapes".
  5.  
  6.     Created        9/2/92        - Dave Hersey
  7.  
  8.     ----------------------------------------------
  9.  
  10.     2/93    debugged and plopped on GX CD.  - dmh
  11.     9/93    updated to run with the ß2 "GXified" interface files. - PLA
  12.     12/93    updated for b3.  - dmh
  13.     3/94    updated for b4.  - dmh
  14.     3/94    general cleanup/debugging. - dmh
  15.     5/94    …and some more. - dmh
  16.     8/94    universalized. - dmh
  17. */
  18.  
  19. #include <stdio.h>
  20. #include <font library.h>
  21. #include <GXExceptions.h>
  22. #include <graphics libraries.h>
  23. #include <graphics toolbox.h>
  24. #include <graphics debugging.h>
  25. #include <qd library.h>
  26. #include <PrintingManager.h>
  27. #include <PrintingResTypes.h>
  28. #include <PrintingMessages.h>
  29. #include <Collections.h>
  30.  
  31. #include "Banana Jr.h"
  32.  
  33.  
  34. /*------ SetUpEditMenuRec ------------------------------------------------------------------------------------*/
  35. //
  36. //    This routine sets up an gxEditMenuRecord which references our edit menu.  This structure
  37. //    is used by the GXJobDefaultFormatDialog and GXJobPrintDialog calls to allow cut, copy,
  38. //    & paste operations from the dialogs.
  39. //
  40. void SetUpEditMenuRec(gxEditMenuRecord *edMenuRec)
  41. {
  42.  
  43.     edMenuRec->editMenuID = mEdit;
  44.     edMenuRec->cutItem = iCut;
  45.     edMenuRec->copyItem = iCopy;
  46.     edMenuRec->pasteItem = iPaste;
  47.     edMenuRec->clearItem = iClear;
  48.     edMenuRec->undoItem = iUndo;
  49. }
  50.  
  51.  
  52. /*------ DoDocFormat ---------------------------------------------------------------------------------*/
  53. //
  54. //    This routine performs GX's equivalent of the Page Setup (PrStlDialog) call of
  55. //    the old printing architecture.
  56. //
  57. OSErr DoDocFormat(WindowPtr wind, gxDialogResult    *result)
  58. {
  59.     OSErr            err;
  60.     gxEditMenuRecord    edMenuRec;
  61.     gxJob                docJob;
  62.     TH_Doc            doc;
  63.  
  64. //    If we have a non-nil WindowPtr, set up our edit menu record and handle the job
  65. //    format dialog.  Remember to check for errors.
  66.  
  67.     if (wind)
  68.     {
  69.         doc = GetDoc(wind);
  70.         docJob = GetDocJob(doc);
  71.         SetUpEditMenuRec(&edMenuRec);
  72.  
  73.         *result = GXJobDefaultFormatDialog(docJob, &edMenuRec);
  74.         err = GXGetJobError(docJob);
  75.     }
  76.     
  77.     return err;
  78. }
  79.  
  80.  
  81. /*------ DoPageFormat ------------------------------------------------------------------------------*/
  82. //
  83. //    This routine performs a by-page format.  In other words, it sets formatting info
  84. //    for only the current page.
  85. //
  86. OSErr DoPageFormat(WindowPtr wind, gxDialogResult *result)
  87. {
  88.     OSErr                err = noErr;
  89.     gxEditMenuRecord    edMenuRec;
  90.     gxJob                docJob;
  91.     TH_Doc                doc;
  92.     TH_Page                docPage;
  93.     gxFormat            pageFormat;
  94.  
  95. //    If we have a non-nil WindowPtr, set up our edit menu record and handle the job
  96. //    format dialog.  Remember to check for errors.
  97.  
  98.     if (wind)
  99.     {
  100.         SetUpEditMenuRec(&edMenuRec);
  101.         doc = GetDoc(wind);
  102.         docJob = GetDocJob(doc);
  103.         docPage = GetDocPage(doc, (*doc)->curPage);
  104.         pageFormat = (*docPage)->pageFormat;
  105.  
  106.         *result = GXFormatDialog(pageFormat, &edMenuRec, nil);
  107.         
  108.         if (*result == gxRevertSelected)
  109.         {
  110.             GXDisposeFormat(pageFormat);
  111.             (*docPage)->pageFormat = GXNewFormat(docJob);
  112.         }
  113.         
  114.         err = GXGetJobError(docJob);
  115.     }
  116.     
  117.     return err;
  118. }
  119.  
  120.  
  121. /*------ DoPrinting ----------------------------------------------------------------------------------*/
  122. //
  123. //    This routine performs GX's equivalent of the PrJobDialog call in the old
  124. // printing architecture, and then prints the document if the user wants to.
  125. //
  126. OSErr DoPrinting(WindowPtr wind)
  127. {
  128.     OSErr                err = noErr;
  129.     gxDialogResult        result;
  130.     gxEditMenuRecord    edMenuRec;
  131.     gxJob                docJob;
  132.     TH_Doc                doc;
  133.     gxFormat            jobFormat;
  134.     gxMapping            formatMapping;
  135.     gxViewPort            formatVPort;
  136.  
  137. //    If we have a non-nil WindowPtr, set up our edit menu record and handle the print
  138. //    job dialog.  Remember to check for errors.  If no errors occur, and the user clicks
  139. //  ok, print the window's document.
  140.  
  141.     if (wind)
  142.     {
  143.         doc = GetDoc(wind);
  144.         docJob = GetDocJob(doc);
  145.         
  146.         SetUpEditMenuRec(&edMenuRec);
  147.         result = GXJobPrintDialog(docJob, &edMenuRec);
  148.         err = GXGetJobError(docJob);
  149.                 
  150.         if ((result == gxOKSelected) && !(err))
  151.             err = DoPrintLoop(wind);
  152.     }
  153.     
  154.     return err;
  155. }
  156.  
  157.  
  158. /*******************************************************************
  159.     MyPrintOneCopy sets up our job collection items for printing
  160.     one copy of a document, and then prints the document.
  161.     
  162. ********************************************************************/
  163.  
  164. OSErr MyPrintOneCopy(WindowPtr wind)
  165. {
  166.     OSErr                    err;
  167.     Collection                jobCollection;
  168.     gxCopiesInfo            copiesInfo;
  169.     gxFileDestinationInfo    destInfo;
  170.     gxPageRangeInfo            pageRangeInfo;
  171.     Ptr                        oldCopiesInfo = nil, oldPageRangeInfo = nil, oldDestInfo = nil;
  172.     long                    oldCopiesSize, oldPageRangeInfoSize, oldDestInfoSize;
  173.     TH_Doc                    doc = GetDoc(wind);
  174.  
  175.  
  176. /* Get the job collection and set it up to print one copy…    */
  177.  
  178.     jobCollection = GXGetJobCollection(GetDocJob(doc));
  179.  
  180.  
  181. /* Set number of copies to 1.            */
  182.     
  183.     copiesInfo.copies = 1;
  184.     err = MyReplaceCollectionItem(&copiesInfo, sizeof(gxCopiesInfo),
  185.                                     gxCopiesTag, gxPrintingTagID,
  186.                                     jobCollection, &oldCopiesInfo, &oldCopiesSize);
  187.     nrequire(err, ReplaceCopies_error);
  188.  
  189.  
  190. /* Set page range to "all".    */
  191.     
  192.     pageRangeInfo.simpleRange.optionChosen = gxDefaultPageRange;
  193.     pageRangeInfo.minFromPage = 1;
  194.     pageRangeInfo.simpleRange.fromPage = 1;
  195.     pageRangeInfo.maxToPage = (*doc)->numPages;
  196.     pageRangeInfo.simpleRange.toPage = (*doc)->numPages;
  197.     pageRangeInfo.simpleRange.printAll = true;
  198.     err = MyReplaceCollectionItem(&pageRangeInfo, sizeof(gxPageRangeInfo),
  199.                                     gxPageRangeTag, gxPrintingTagID,
  200.                                     jobCollection, &oldPageRangeInfo, &oldPageRangeInfoSize);
  201.     nrequire(err, ReplacePageRange_error);
  202.  
  203.  
  204. /* Set destination to "printer".        */
  205.  
  206.     destInfo.toFile = false;
  207.     err = MyReplaceCollectionItem(&destInfo, sizeof(gxFileDestinationInfo),
  208.                                   gxFileDestinationTag, gxPrintingTagID,
  209.                                   jobCollection, &oldDestInfo, &oldDestInfoSize);
  210.     nrequire(err, ReplaceDestination_error);
  211.  
  212.  
  213. /* Print one copy of our document.        */
  214.  
  215.     err = DoPrintLoop(wind);
  216.  
  217.  
  218. /*    Restore original number of copies, page range, and output
  219.     destination in case anybody uses that info. */
  220.  
  221. ReplaceCopies_error:
  222.     MyReplaceCollectionItem(oldCopiesInfo, oldCopiesSize,
  223.                               gxCopiesTag, gxPrintingTagID,
  224.                             jobCollection, nil, nil);
  225.  
  226. ReplacePageRange_error:
  227.     MyReplaceCollectionItem(oldPageRangeInfo, oldPageRangeInfoSize,
  228.                             gxPageRangeTag, gxPrintingTagID,
  229.                             jobCollection, nil, nil);
  230.  
  231. ReplaceDestination_error:
  232.     MyReplaceCollectionItem(oldDestInfo, oldDestInfoSize,
  233.                             gxFileDestinationTag, gxPrintingTagID,
  234.                             jobCollection, nil, nil);
  235.  
  236.  
  237. /* Dispose of the pointers that MyReplaceCollectionItem created. */
  238.  
  239.     if (oldCopiesInfo)
  240.         DisposePtr(oldCopiesInfo);
  241.  
  242.     if (oldPageRangeInfo)
  243.         DisposePtr(oldPageRangeInfo);
  244.  
  245.     if (oldDestInfo)
  246.         DisposePtr(oldDestInfo);
  247.  
  248.     return err;
  249. }
  250.  
  251.  
  252.  
  253. /*******************************************************************
  254.     MyReplaceCollectionItem is a generic routine that replaces a
  255.     collection item with the passed data.  If the oldData parameter
  256.     is not nil, this routine creates a pointer and returns the data
  257.     that's being replaced in it.  (If the item doesn't already exist,
  258.     then a copy of the newData is returned instead.)
  259.     
  260. ********************************************************************/
  261.  
  262. OSErr MyReplaceCollectionItem(void *newData, long collectSize,
  263.                               OSType collectType, long collectID,
  264.                               Collection whichCollection,
  265.                               Ptr *oldData, long *oldDataSize)
  266. {
  267.     OSErr    err = noErr;
  268.     long    index;
  269.  
  270. /*
  271.     If we're supposed to return the old data, get it.
  272.     If there is no old data, return a copy of the new data.
  273. */
  274.  
  275.     if (oldData)
  276.     {
  277.         err = GetCollectionItemInfo(whichCollection,
  278.                                     collectType,
  279.                                     collectID,
  280.                                     dontWantIndex,
  281.                                     oldDataSize,
  282.                                     dontWantAttributes);
  283.  
  284.         if (err)
  285.         {
  286.             *oldDataSize = collectSize;
  287.             *oldData = NewPtrSys(*oldDataSize);
  288.             if (!(err = MemError()))
  289.                 BlockMove(newData, *oldData, collectSize);
  290.         }
  291.         else
  292.         {
  293.             *oldData = NewPtrSys(*oldDataSize);
  294.             if (!(err = MemError()))
  295.                 err = GetCollectionItem(whichCollection,
  296.                                         collectType,
  297.                                         collectID,
  298.                                         dontWantSize,
  299.                                         *oldData);
  300.         }
  301.     }
  302.  
  303.     nrequire(err, CouldNotSetOldData);
  304.  
  305.  
  306. // If we're adding a new collection item, do so.  Otherwise, get the
  307. // existing item's index and replace the old collection item.
  308.  
  309.     err = AddCollectionItem(whichCollection,
  310.                             collectType,
  311.                             collectID,
  312.                             collectSize,
  313.                             newData);
  314.  
  315.     if (err == collectionItemLockedErr)
  316.     {
  317.         err = GetCollectionItemInfo(whichCollection,
  318.                                     collectType,
  319.                                     collectID,
  320.                                     &index,
  321.                                     dontWantSize,
  322.                                     dontWantAttributes);
  323.         if (!err)
  324.             err = ReplaceIndexedCollectionItem(whichCollection,
  325.                                                index,
  326.                                                collectSize,
  327.                                                newData);
  328.     }
  329.  
  330. CouldNotSetOldData:
  331.     return err;
  332. }
  333.  
  334.  
  335.  
  336. /*------ DoPrintLoop ----------------------------------------------------------------------------------*/
  337. //
  338. //    This routine prints the window's document using whatever job and format
  339. //    is currently attached to it.  (If the window wwere just created and then the user
  340. //    selected Print One Copy w/o first selecting Page Setup…, the system default job and
  341. //    format are stored with this document.
  342. //
  343. OSErr DoPrintLoop(WindowPtr wind)
  344. {
  345.     OSErr        err = noErr;
  346.     gxJob        docJob;
  347.     Str255        title;
  348.     TH_Doc        doc;
  349.     TH_Page        docPage;
  350.     gxFormat    pageFormat;
  351.     gxShape     pageShape, coverPage;
  352.     long        firstPg, lastPg, pg, numPages;
  353.  
  354. //    If we have a non-nil WindowPtr, start the print job, print a page and then finish
  355. //    the job.  Remember to check those errors!
  356.  
  357.     if (wind)
  358.     {
  359.         doc = GetDoc(wind);
  360.         docJob = GetDocJob(doc);
  361.         numPages = (*doc)->numPages;
  362.         GetWTitle(wind, title);
  363.         
  364.         GXGetJobPageRange(docJob, &firstPg, &lastPg);
  365.  
  366.         firstPg = (firstPg < 1)? 1: (firstPg > numPages)? numPages: firstPg;
  367.         lastPg = (lastPg < firstPg)? firstPg: (lastPg > numPages)? numPages: lastPg;
  368.         numPages = lastPg - firstPg +1;
  369.         
  370.         GXStartJob(docJob, title, numPages);
  371.         err = GXGetJobError(docJob);
  372.         
  373.         for (pg = firstPg; (!err) && (pg <= lastPg); pg++)
  374.         {
  375.             docPage = GetDocPage(doc, pg);
  376.             pageFormat = (*docPage)->pageFormat;
  377.             pageShape = GXCopyToShape(nil, GetDocShape(doc, pg));
  378.             CheckForIdiots(pageFormat, pageShape);
  379.  
  380.             GXPrintPage(docJob, pg, pageFormat, pageShape);
  381.             
  382.             GXDisposeShape(pageShape);
  383.             err = GXGetJobError(docJob);
  384.         }
  385.  
  386.         GXFinishJob(docJob);
  387.         if (!err) err = GXGetJobError(docJob);
  388.     }
  389.     return err;
  390. }
  391.  
  392.  
  393. void CheckForIdiots(gxFormat aFormat, gxShape pageShape)
  394. {
  395.     OSErr                    err;
  396.     Collection                fmtCollection;
  397.     T_BananaCollection        bananaConfig;
  398.     gxShape                     theText;
  399.     Str255                    textStr;
  400.     long                    numChars;
  401.     
  402.     fmtCollection = GXGetFormatCollection(aFormat);
  403.  
  404.     err = GetCollectionItem(fmtCollection, kBananaCollectionType,
  405.                               gxPrintingTagID, nil, &bananaConfig);
  406.     
  407.     if (!err)
  408.     {
  409.         if (bananaConfig.one || bananaConfig.two ||
  410.             bananaConfig.three || bananaConfig.four)
  411.         {
  412.             theText = GXNewShape(gxTextType);
  413.             GXSetShapeTextSize(theText, ff(32));
  414.             SetShapeCommonFont(theText, timesFont);
  415.             GXMoveShapeTo(theText, ff(10), ff(40));
  416.  
  417.             if (bananaConfig.two)    // Idiots setting
  418.             {
  419.                 numChars = sprintf((Ptr) &textStr[0], "%s", "Idiots enabled.");
  420.                 GXSetText(theText, numChars, textStr, nil);
  421.  
  422.                 AddToShape(pageShape, theText);
  423.                 GXMoveShape(theText, ff(0), ff(40));
  424.             }
  425.  
  426.             if (bananaConfig.three)    // Random Printing setting
  427.             {
  428.                 numChars = sprintf((Ptr) &textStr[0], "%s", "Random Printing Enabled.");
  429.                 GXSetText(theText, numChars, textStr, nil);
  430.  
  431.                 AddToShape(pageShape, theText);
  432.                 GXMoveShape(theText, ff(0), ff(40));
  433.             }
  434.  
  435.             if (bananaConfig.four)    // Page Shuffling setting
  436.             {
  437.                 numChars = sprintf((Ptr) &textStr[0], "%s", "Page Shuffling enabled.");
  438.                 GXSetText(theText, numChars, textStr, nil);
  439.  
  440.                 AddToShape(pageShape, theText);
  441.                 GXMoveShape(theText, ff(0), ff(40));
  442.             }
  443.  
  444.             if (bananaConfig.one)    // 360° Rotation setting
  445.             {
  446.                 numChars = sprintf((Ptr) &textStr[0], "%s", "360° Rotation enabled.");
  447.                 GXSetText(theText, numChars, textStr, nil);
  448.  
  449.                 AddToShape(pageShape, theText);
  450.             }
  451.  
  452.             GXDisposeShape(theText);
  453.         }
  454.     }
  455. }
  456.  
  457.  
  458.  
  459.  
  460.  
  461.  
  462.